<?php

namespace Api\Controller;

use Think\Controller;
use Utuo\WechatApi;
use Utuo\Sign;
use Utuo\WechatAdvance;
use Home\Logic\DistributionShopLoginScoreLogic;
use Utuo\WechatAdvance\QrCode;
use Utuo\WechatUserLogin;
use Utuo\WechatAdvance\Media;
use Utuo\DBRW;
use My\Model\UserRole;
use My\Model\WechatUserModel;
use Api\Utils\MicroShowUtil;
use Home\Logic\ScoreEventLogic;
use Utuo\DistributionShopScore;
use My\Model\DistributionShopModel;
use Utuo\SystemInfo;

class WechatController extends Controller {
	
	// 权限用户id
	private $authId = 0;
	
	// 是否启用多客服系统
	private $customerServiceEnabled = true;
	
	public function _initialize() {
		$this->authId = I("get.id", 0, 'intval');
		error_reporting(0);
	}
	
	/**
	 * 响应我的二维码
	 * @param unknown $wechat
	 * @param unknown $openId
	 */
	public function reponseQrCode ($wechat, $openId) {
		$user = M("WechatUser")->where(array('openId'=>$openId, 'cid'=>$this->authId))->find();
		$tag = 'default';
		$type =  QrCode::QR_ACTION_FOREVER;
		$data = array();
		$util = \Api\Utils\QrcodeUtil::getInstance(array(
				'cid' => $this->authId,
				'openId' => $openId,
				'modelName' => 'DistributionShop',
		));
		$qrConfig = $util->getConfig();
		$qrConfig = $qrConfig["qrConfig"];
		if ( !isset($qrConfig['opening']) or !$qrConfig['opening'] ) {
    		$userRole = new UserRole();
    		$userRole->type($user['type']);
    		if ( $userRole->isNot(WechatUserModel::USER_TYPE_AGENT) and $userRole->isNot(WechatUserModel::USER_TYPE_FRANCHISED_DEALER) ) {
    			$wechat->responseText("您还不是金牌会员或代理不能生成二维码哦~({$user['type']})");
    		}
		}
		$result = $util->getQrcode($type, $tag); // 获得推广二维码
		if ( empty($result['url']) ) {
			$wechat->responseText('抱歉，未能生成二维码请重试.('.$util->errorCode.')');
		}
		/* 获得推广图 */
		$myCodeImage = $util->findQrPromotionImages($result['codeId']);
		
		/** 设置生成二维码的字段属性 */
		/* 获得用户信息 */
		if ( $util->fieldExist('face') or $util->fieldExist('nickname') ) {
			$wechatConfig = M('Wechat')->where("cid={$this->authId}")->field('appid,appsecret')->find();
			if ( $wechatConfig ) {
				$wechatAdvance = new WechatAdvance($wechatConfig['appid'], $wechatConfig['appsecret']);
				// 设置登录接口
				$login = WechatUserLogin::newInstance(array(
						'cid' => $this->authId,
						'wechatAdvance' => $wechatAdvance,
				));
				$wechatUser = $login->bindUser(array('openId' => $openId));
				if ( $wechatUser ) {
				    if ( (empty($wechatUser['face']) or empty($wechatUser['nickname'])) ) {
				        $accessToken = $wechatAdvance->getBaseAccess( $openId );
				        $userInfo = $wechatAdvance->getUserInfo( $accessToken['access_token'], $openId );
				        $userInfo and $wechatUser = $login->bindUser(array( 'openId' => $openId, ), $userInfo);
				    }
				    if ( $util->fieldExist('face') ) {
				        if ( !empty($wechatUser['face']) ) {
				            $faceImageInfo = getimagesize($wechatUser['face']);
				            $createDsfun = str_replace('/', 'createfrom', $faceImageInfo['mime']); // 创建目标图函数
				            $util->setFieldValue("face", "img", $wechatUser['face']);
				            $util->setFieldValue("face", "createFun", $createDsfun);
				        } else {
    				        $wechat->responseText('未能生成二维码，您还没有设置微信头像');
    				    }
				    }
				    if ( $util->fieldExist('nickname') ) {
				        if ( !empty($wechatUser['nickname']) ) {
    				        $util->setFieldValue("nickname", "text", $wechatUser['nickname']);
				        } else {
				            $wechat->responseText('未能生成二维码，您还没有设置微信昵称');
				        }
				    }
				} else {
				    $wechat->responseText('未能绑定用户到公众平台，请重试');
				}
			}
		}
		$util->setFieldValue("qrcode", "img", $result['image']);
		$util->setFieldValue("qrcode", "createFun", "imagecreatefromstring");
		
		$isChange = 0;
		// 重新生成二维码推广图
		if ( (isset($result['isChange']) and $result['isChange']) or !$myCodeImage or ($util->getQrConfigMd5() != $myCodeImage['configMd5']) ) {
			/* 保存推广图到文件 */
			$myCodeImageNew = $util->drawQrcode();
			$url = $util->saveFile('wmei5', $myCodeImageNew);
			/* 保存推广图到数据库 */
			$data = array(
					'codeId' => $result['codeId'],
					'url' => $url,
					'configMd5' => $util->getQrConfigMd5(),
			);
			$myCodeImage and $data['id'] = $myCodeImage['id'];
			$r = $util->submitQrPromotionImages( $data );
			if ( false == $r ) {
			    // 响应二维码宣传图
			    $wechat->responseImage('网络延时请重试~');
			} elseif ( !$myCodeImage ) {
				$data['id'] = $r;
				$myCodeImage = $data;
			} else {
				$myCodeImage = array_merge($myCodeImage, $data);
			}
			$isChange = 1; // 有新的二维码创建或二维码发生改变
			$uploadMedia = $myCodeImageNew;
		}
		// 上传媒体文件到微信
		$isTimeout = false;
		if ( !$isChange and (time() - $myCodeImage['mediaCreateTime']*1) > 3*24*60*60-3600 ) { // 上传超时(3天内有效期)
			// 加载已生成的图片
			$imgInfo = getimagesize($myCodeImage['url']);
			$createfun = str_replace('/', 'createfrom', $imgInfo['mime']); // 创建目标图函数
			$img = $createfun($myCodeImage['url']);
			// 获得图片二进制数据
			ob_start();
			$fun = str_replace('/', '', $imgInfo['mime']);
			$fun($img);
			$imgstr = ob_get_contents();
			ob_end_clean();
			imagedestroy($img);
			$uploadMedia = array(
				'content' => $imgstr,
				'mime' => $imgInfo['mime'],
			);
			$isTimeout = true;
		}
		if ( $isChange or $isTimeout ) {
			$wechatAdvance = $util->getWechatAdvance();
			$media = $wechatAdvance->mediaUpload( $uploadMedia, Media::MEDIA_TYPE_IMAGE );
			$util->submitQrPromotionImages( array(
					'id' => $myCodeImage['id'],
					'mediaId' => $media['media_id'],
					'mediaCreateTime' => $media['created_at'],
			) );
			$myCodeImage['mediaId'] = $media['media_id'];
		}
		// 响应二维码宣传图
		$wechat->responseImage($myCodeImage['mediaId']);
	}
	
	// 消息响应
	public function indexAction() {
		$time = time();
		$wechat = new WechatApi(true);
		$wechat->setResponseTime($time);
		
		// 处理接口验证
		if ($wechat->isValid()) {
			$token = M('Wechat')->where("cid={$this->authId}")->getField('token');
			$wechat->valid($token);
			return;
		}
		
		$wechatConfig = M('Wechat')->where("cid={$this->authId}")->field('appid,appsecret')->find();
		
		// 发送客服消息
// 		$this->customerServiceEnabled && $wechat->responseCustomerService();
		
		// 以下处理消息响应
		$msgType = $wechat->getMsgType();
		$d = D("My/WechatReply", "Model");
		switch ($msgType) {
			case $wechat::TYPE_TEXT :
				$openId = $wechat->getUserName();
				$keyword = $wechat->getContent();
				
				if ( $keyword == '我的二维码' ) {
					$this->reponseQrCode($wechat, $openId);
				}
				
				/* 微秀 */
				$job = MicroShowUtil::getOnWork($this->authId, $openId);
				if ( $job ) {
					if( strtolower($keyword) == 'over' ) {
					    $job['config'] and $job['config'] = unserialize($job['config']);
						MicroShowUtil::finished($this->authId, $job['id']);
						foreach (  $job['config'] as $v0) {
						    if ( $v0['type'] == 'image' ) {
						        $job['coverImage'] = $v0['url'];
						        break;
						    }
						}
						$t = time();
						$linkUrl = U("Home/MicroShow/modify", array('id'=>$job['id'], 'sid'=>$job['cid']), false, true);
						$urlConfig = parse_url($linkUrl);
						$sign = Sign::create( array("open_id"=>$openId, "_t"=>$t));
						$linkUrl.= (!empty($urlConfig['query']) ? "&":"?")."open_id=".$wechat->getUserName()."&_s=".$sign."&_t=".$t;
						$materialLists = array();
						$data = array(
						    $job['title'],
						    $job['title'],
						    $job['coverImage'],
						    $linkUrl,
						);
						$materialLists[] = $data;
						$wechat->responseNewsLists($materialLists);
					} else {
						$job['config'] or $job['config'] = array();
						$job['config'] and $job['config'] = unserialize($job['config']);
						$job['config'][time()] = array(
							'type' => 'text',
							'content' => $keyword,
						);
						$job['config'] = serialize($job['config']);
						MicroShowUtil::save($job);
						$wechat->responseText("回复over结束，或继续上传图片或增加文字.");
					}
				} else {
					if ( strtolower($keyword) == 'go' ) {
						MicroShowUtil::addMyShow($this->authId, $openId);
						$wechat->responseText("新建微秀成功，现在可以向新建的微秀中上传图片或增加文字了，回复over结束。");
					}
				}
				
				$condition = array(
						'rule' => array(
								'not in',
								array(
										$d->ruleSubscribe,
										$d->ruleAnything,
										$d->ruleMenu
								) 
						),
						"cid" => $this->authId,
						'status' => 1,
						'is_deleted' => 0,
						'keyword' => array(
								'exp',
								" like '%," . $keyword . ",%'" 
						) 
				);
				$reply = $d->where($condition)->order('id desc')->find();
				if ( $reply ) {
					$this->responseMsg($wechat, $reply);
				}
				break;
			case $wechat::TYPE_IMAGE : 
			    $openId = $wechat->getUserName();
				/* 微秀 */
				$job = MicroShowUtil::getOnWork($this->authId, $openId);
				if ( $job ) {
					$job['config'] or $job['config'] = array();
					$job['config'] and $job['config'] = unserialize($job['config']);
					$job['config'][time()] = array(
							'type' => 'image',
							'url' => $wechat->getData("PicUrl"),
							'mediaId' => $wechat->getData("MediaId"),
							'msgId' => $wechat->getData("MsgId"),
					);
					$job['config'] = serialize($job['config']);
					MicroShowUtil::save($job);
					$wechat->responseText("回复over结束，或继续上传图片或增加文字.");
				}
				break;
			case $wechat::TYPE_EVENT :
				// 事件消息
				$event = $wechat->getEvent();
				$openId = $wechat->getUserName();
				$wechatUser = array();
				switch ( $event ) {
					// 关注事件
					case $wechat::EVENT_SUBSCRIBE :
						$eventKey = $wechat->getEventKey();
						/* 关注获得最新用户信息 */
						$userInfo = array();
						try {
							if ( $wechatConfig ) {
								$wechatAdvance = new WechatAdvance($wechatConfig['appid'], $wechatConfig['appsecret']);
								if ( $wechatAdvance->getError() ) {
								    $wechatAdvance = null;
								} else {
								    $accessToken = $wechatAdvance->getBaseAccess( $openId );
								    $userInfo = $wechatAdvance->getUserInfo( $accessToken['access_token'], $openId );
								    /* 设置登录接口 */
								    $login = WechatUserLogin::newInstance(array(
								        'cid' => $this->authId,
								        'wechatAdvance' => $wechatAdvance,
								    ));
								    /* 扫描带参数二维码事件(还未关注公众号) */
								    if ( !empty( $eventKey ) ) {
								        $ticket = $wechat->getData('Ticket'); // 可用来换取二维码图片
								        //$eventKey = $wechat->getData('EventKey'); // qrscene_1
								        $sceneId = substr($eventKey, strlen('qrscene_'));
								        if ( $sceneId ) {
								            /* 二维码图片推广者 */
								            $isOverdue = false;
								            $qrCode = M("QrCode")->where(array('senceId' => $sceneId, 'cid' => $this->authId,))->find();
								            $muser = array(); // 二维码主人用户信息
								            if ( $qrCode ) {
								                $muserId = $qrCode['uid'];
								                $muser = M("WechatUser")->where("cid=%d and id=%d", $this->authId, $muserId)->find();
								                if ( empty($muser) ) {
								                    $isOverdue = true;
								                }
								                $qpi = M("QrPromotionImages")->where(array('codeId'=>$qrCode['id']))->find();
								                if ( empty($qpi) ) {
								                    $isOverdue = true;
								                }
								            } else {
								                $isOverdue = true;
								            }
								            if ( $isOverdue ) {
								                $wechat->responseText("您扫描的二维码不正确或已过期,请取消关注并从推广人那里重新获得二维码~");
								            }
								            /* 绑定扫码用户信息  */
								            $wechatUser = $login->bindUser(array( 'mid' => $muser['id'], 'openId' => $openId, ), $userInfo);
								        }
								    } else {
								        /* 更新微信用户表 */
								         $wechatUser = $login->bindUser(array( 'openId' => $openId, 'subscribeTime' => $time), $userInfo);
								    }
								}
							}
						} catch (\Exception $e) {
						    $wechat->responseText($e->getMessage());
						}
						
						/* 关注用户 */
						$firstSubscribe = false;
						if ( isset($wechatUser['isNew']) and $wechatUser['isNew'] ) {
						    $firstSubscribe = true;
						}
						
						/* 关注有返回消息时(攒支持) */
						$refererInfo = S("referer_{$this->authId}_{$openId}"); // and $refererInfo['nickname'] and $refererInfo['goodsName'] and $refererInfo['link']
						if ( $refererInfo and !empty($userInfo) ) {
							/* 客服消息回复 */
							$data = array(
									"articles" => array(
										array(
											'title' => sprintf("亲爱的  %s 您好：", $userInfo['nickname']),
											'description' => "您的好友 {$refererInfo['nickname']} 正在参加\"{$refererInfo['goodsName']}\"活动，点击查看全文进入活动页面支持Ta吧!",
											'url' => $refererInfo['link'],
										)
									)
							);
							$wechatAdvance->sendServerMessage( $accessToken['access_token'], $openId, $data, 5 );
							S("referer_{$this->authId}_{$openId}", null);
						}
						
						/* 关注积分 */
						if ( $firstSubscribe ) {
						    $shopConfig = D("My/DistributionShop")->getShopConfig($this->authId);
						    if ( !empty($shopConfig) and !empty($shopConfig['status']) and $shopConfig['status']) {
						        /* 关注人积分奖励 */
						        $result = ScoreEventLogic::checkStatus($shopConfig, 'FirstSubscribe');
						        if ( $result['check'] ) {
						            if ( $wechatUser ) {
						                $scoreHandle = DistributionShopScore::getInstance("FirstSubscribe", array('cid'=>$this->authId, 'uid' => $wechatUser['id']), $result['driverConfig']);
						                $scoreHandle->exec();
						            }
						        }
						        /* 上线积分奖励 */
						        $result = ScoreEventLogic::checkStatus($shopConfig, 'DownlineSubscribe');
						        if ( $result['check'] ) {
						            if ( $wechatUser ) {
						                $scoreHandle = DistributionShopScore::getInstance("DownlineSubscribe", array('cid'=>$this->authId, 'uid' => $wechatUser['mid']), $result['driverConfig']);
						                $scoreHandle->exec();
						            }
						        }
						    }
						}
						
						/* 关注回复 */
						$reply = $d->where(array(
								"cid"=> $this->authId,
								"rule" => $d->ruleSubscribe 
						))->find();
						
						if ( $reply ) {
							$this->responseSubscribeMsg($wechat, $reply, $userInfo);
						}
						
						$wechat->responseText("感谢您的关注！");
						
						break;
						
					case $wechat::EVENT_UNSUBSCRIBE : // 取消关注事件
						
						break;
					
					
					case $wechat::EVENT_SCAN : // 扫描带参数二维码事件(已关注时)
						$data = $wechat->getData(0);
						$sceneId = $wechat->getEventKey();
						$openId = $wechat->getUserName();
						if ( $sceneId ) {
						    $wechatAdvance = new WechatAdvance($wechatConfig['appid'], $wechatConfig['appsecret']);
						    $accessToken = $wechatAdvance->getBaseAccess( $openId );
						    $userInfo = $wechatAdvance->getUserInfo( $accessToken['access_token'], $openId );
						    // 设置登录接口
						    $login = WechatUserLogin::newInstance(array(
						        'cid' => $this->authId,
						        'wechatAdvance' => $wechatAdvance,
						    ));
						    
						    /* 二维码图片推广者 */
						    $isOverdue = false;
						    $qrCode = M("QrCode")->where(array('senceId' => $sceneId, 'cid' => $this->authId,))->find();
						    if ( $qrCode ) {
						        $muserId = $qrCode['uid'];
						        $muser = M("WechatUser")->where("cid=%d", $this->authId)->find($muserId);
						        if ( empty($muser) ) {
						            $isOverdue = true;
						        }
						        $qpi = M("QrPromotionImages")->where(array('codeId'=>$qrCode['id']))->find();
						        if ( empty($qpi) ) {
						            $isOverdue = true;
						        }
						    } else {
						        $isOverdue = true;
						    }
						    if ( $isOverdue ) {
						        $wechat->responseText("您扫描的二维码已过期~");
						    }
						    /* 绑定扫码用户信息  */
						    $dd =  $login->bindUser(array( 'mid' => $muser['id'], 'openId' => $openId, ) , $userInfo);
						    if ( $dd ) {
						        $wechat->responseText('扫码成功 ，欢迎您回来~'."{$this->authId}-{$muserId}-{$sceneId}");
						    }
						}
						break;
						
					case $wechat::EVENT_CLICK : // 菜单点击
						$openId = $wechat->getUserName();
						$eventKey = $wechat->getEventKey();
						$reply = $d->where(array(
								"cid" => $this->authId,
								"rule" => $d->ruleMenu,
								"keyword" => $eventKey,
						))->find();
						
						if ( $reply ) {
							if ( $eventKey == '签到' ) { /* 点击菜单签到  */
								
							} elseif ( $eventKey == '我的二维码' ) {  /* 点击菜单领二维码  */
								$this->reponseQrCode($wechat, $openId);
							}
							$this->responseMsg($wechat, $reply);
						}
						
						$wechat->responseText("敬请期待哦~");
						break;
						
					case $wechat::EVENT_LOCATION : // 连接点击
						exit;
						break;
						
					default:
						break;
				}
				break;
			default:
				break;
		}
		
		// 响应任意消息回复内容
		$helpReply = $d->where(array(
				"cid" => $this->authId,
				"rule" => $d->ruleAnything 
		))->find();
		if ( $helpReply ) {
			$this->responseMsg($wechat, $helpReply);
		} else {
			$wechat->responseCustomerMsg();
		}
		
		$wechat->responseText("你好，消息已经收到！");
	}
	
	// 关注响应消息
	private function responseSubscribeMsg($wechat, $reply, $userInfo) {
		// 发送响应消息
		if ($reply['type'] == $wechat::TYPE_TEXT) {
			$wechat->responseText($reply['text']);
		} elseif ($reply['type'] == $wechat::TYPE_NEWS) {
			$materials = D("WechatMaterial")->field("id,title,type,cover_url,description,url")->where(array(
					"id" => array(
							'in',
							$reply['news']
					)
			))->order("field(id," . $reply['news'] . ")")->select();
			$materialLists = array();
			foreach ($materials as $v) {
				if ($v['type'] == 'news') {
					$url = $this->getNewsUrl($v['id']);
				} elseif ($v['type'] == 'url') {
					$url = $v['url'];
				}
				$urlConfig = parse_url($url);
				$data = array(
						str_replace(array('{nickname}'), array($userInfo['nickname']), $v['title']),
						$v['description'],
						str_replace(array('{face}'), array($userInfo['headimgurl']), $v['cover_url']),
						$url.(!empty($urlConfig['query']) ? "&":"?")."open_id=".$wechat->getUserName(),
				);
				$materialLists[] = $data;
			}
			$wechat->responseNewsLists($materialLists);
		} elseif ($reply['type'] == 'link') {
			$urlConfig = parse_url($reply['link_url']);
			$timestamp = time();
			$sign = Sign::create( array("open_id"=>$wechat->getUserName(), "_t"=>$timestamp));
			$reply['link_url'].= (!empty($urlConfig['query']) ? "&":"?")."open_id=".$wechat->getUserName()."&_s=".$sign."&_t=".$timestamp;
			$wechat->responseNews($reply['link_title'], $reply['link_description'], $reply['link_pic'], $reply['link_url']);
		}
	}
	
	// 响应消息
	private function responseMsg($wechat, $reply) {
	    empty($reply) && $wechat->responseText('消息已收到!');
	    // 发送响应消息
		if ($reply['type'] == $wechat::TYPE_TEXT) {
		    empty($reply['text']) && $wechat->responseText('消息已收到!');
			$wechat->responseText($reply['text']);
		} elseif ($reply['type'] == $wechat::TYPE_NEWS) {
			$materials = D("WechatMaterial")->field("id,title,type,cover_url,description,url")->where(array(
					"id" => array(
							'in',
							$reply['news'] 
					) 
			))->order("field(id," . $reply['news'] . ")")->select();
			$materialLists = array();
			foreach ($materials as $v) {
				if ($v['type'] == 'news') {
					$url = $this->getNewsUrl($v['id']);
				} elseif ($v['type'] == 'url') {
					$url = $v['url'];
				} else {
				    $url = '';
				}
				$urlConfig = parse_url($url);
				$timestamp = time();
				$sign = Sign::create( array("open_id"=>$wechat->getUserName(), "_t"=>$timestamp));
				$data = array(
						$v['title'],
						$v['description'],
						$v['cover_url'],
						$url.(!empty($urlConfig['query']) ? "&":"?")."open_id=".$wechat->getUserName()."&_s=".$sign."&_t=".$timestamp,
				);
				$materialLists[] = $data;
			}
			$wechat->responseNewsLists($materialLists);
		} elseif ($reply['type'] == 'link') {
			$urlConfig = parse_url($reply['link_url']);
			$timestamp = time();
			$sign = Sign::create( array("open_id"=>$wechat->getUserName(), "_t"=>$timestamp));
			$reply['link_url'].= (!empty($urlConfig['query']) ? "&":"?")."open_id=".$wechat->getUserName()."&_s=".$sign."&_t=".$timestamp;
			$wechat->responseNews($reply['link_title'], $reply['link_description'], $reply['link_pic'], $reply['link_url']);
		}
	}
	
	/**
	 * 获得图文消息链接地址
	 *
	 * @param integer $newsId
	 * @return string
	 */
	private function getNewsUrl($newsId) {
		return "http://" . $_SERVER['HTTP_HOST'] . __CONTROLLER__ . "/news/id/" . $newsId;
	}
	
	/**
	 * 显示图文信息
	 */
	public function newsAction() {
		$id = I('get.id', null, 'intval');
		$news = D("WechatMaterial")->field("id,title,cover_url,description,news")->find($id);
		$this->assign("news", $news);
		layout(false);
		$this->display();
	}
}